using UnityEngine;
using UnityEditor; 
using System.Collections;
using System.Collections.Generic;

using UnityEngine;
using UnityEditor; 
using System.Collections;
using System.Collections.Generic;

[CustomEditor(typeof(CharacterAnimatedState))]  
public class CharacterStateInspector : Editor
{
	private Character character;
	private CharacterAnimatedState state;

	public int currentFrame { get; set; }
	private bool refreshFrames = true;
	private bool[] showFrame = null;
	private Editor[] frameEditors = null;

    private Vector3 initialPosition = Vector3.zero;


	public override void OnInspectorGUI () 
	{

		state = target as CharacterAnimatedState;
		character = state.transform.parent.parent.GetComponent<Character>();
		if(character == null)
		{ 
			EditorGUILayout.LabelField("Character Invalid"); 
			return;
		}
		character.IndexStates();
		state.InitFramesInfo();

		CustomAnimationSampler.CustomSampleAnimation(character, state.animationClip, currentFrame);

		DrawAnimationInfo();
		
		DrawDefaultInspector();
		
		DrawAddFrame();

		DrawFrames();

        UpdatePositionValueGroup();
	}
 
	void DrawFrames()
	{
		CharacterKeyFrame[] frames = state.GetComponentsInChildren<CharacterKeyFrame>();
		
		if(refreshFrames)
		{
			RefreshFrameInspector();
		}
		
		for(int i = 0; i < frames.Length; i++)
		{
			EditorGUILayout.BeginHorizontal();
			showFrame[i] = EditorGUILayout.Foldout(showFrame[i], frames[i].gameObject.name); 
			bool remove = false;
			if(frames[i].always == false)
				remove = GUILayout.Button("Remove"); 
			EditorGUILayout.EndHorizontal();

			if(remove)
			{
				GameObject.DestroyImmediate(frames[i].gameObject);
				refreshFrames = true;
				break;
			}
			else
			{
				if(showFrame[i])
					frameEditors[i].OnInspectorGUI();

			}
		}
	}
 
	void DrawAddFrame()
	{
		if(GUILayout.Button("Add Key Frame"))
		{
			CreateCharacterWizard.AddKeyFrame();
			refreshFrames = true;
		}
	}

	public void DrawAnimationInfo()
	{
		EditorGUILayout.BeginHorizontal();
		EditorGUILayout.LabelField("Duration", GUILayout.MaxWidth(100));
		EditorGUILayout.LabelField(state.duration.ToString());
		EditorGUILayout.EndHorizontal();
		
		EditorGUILayout.BeginHorizontal();
		EditorGUILayout.LabelField("60FPS Frames", GUILayout.MaxWidth(100));
		EditorGUILayout.LabelField(state.frames.ToString());
		EditorGUILayout.EndHorizontal();

		currentFrame = EditorGUILayout.IntSlider("Current Frame", currentFrame, 0, state.frames);
	}

	public void RefreshFrameInspector()
	{
		CharacterKeyFrame[] frames = state.GetComponentsInChildren<CharacterKeyFrame>();

		showFrame = new bool[frames.Length];
		frameEditors = new Editor[frames.Length];
		for(int i = 0; i < frames.Length; i++)
		{
			frameEditors[i] = CreateEditor(frames[i]);
		}

		refreshFrames = false;
	}

    void UpdatePositionValueGroup()
    {
        CharacterKeyFrame[] frames = state.GetComponentsInChildren<CharacterKeyFrame>();
        for(int i = 0; i < frames.Length; i++)
        {
            CharacterAction[] actions = frames[i].GetComponentsInChildren<CharacterAction>();
            foreach(CharacterAction action in actions)
            {
                if(action is PositionByValueGroupOnUpdate)
                {
                    PositionByValueGroupOnUpdate PB = action as PositionByValueGroupOnUpdate;
                    int length = PB.positionGroup.Length;

                    for(int j=0;j<length;j++)
                    {
                        if( currentFrame <= PB.positionGroup[j].frame)
                        {
                            float ratio = 1.0f;
                            if(j == 0)
                            {
                                ratio = (float)(currentFrame) /(float)(PB.positionGroup[j].frame);
                            }
                            else
                            {
                                ratio = (float)(currentFrame - PB.positionGroup[j-1].frame) / (float)(PB.positionGroup[j].frame - PB.positionGroup[j-1].frame);
                            }
                            //Debug.LogError("ratio = "+ ratio + "  currentFrame = "+ currentFrame +"j = " + j);
                            Vector3 sum = Vector3.zero;
                            if(j == 0)
                            {
                                //Debug.LogError("j==0");
                                Vector3 delta = new Vector3(
                                PB.positionGroup[j].right,PB.positionGroup[j].up,PB.positionGroup[j].forward);
                                sum = ratio * delta;
                            }
                            else{
                                for(int m=0;m<j;m++)
                                {
                                    Vector3 delta = new Vector3(
                                        PB.positionGroup[m].right,PB.positionGroup[m].up,PB.positionGroup[m].forward);
                                    sum += delta;
                                    //Debug.LogError("delta" + delta);
                                }
                                Vector3 current = new Vector3(
                                    PB.positionGroup[j].right,PB.positionGroup[j].up,PB.positionGroup[j].forward);
                                sum += ratio * current;
                            }
                            //Debug.LogError("sum = "+ sum);
                            character.gameObject.transform.position = initialPosition + character.transform.TransformDirection(sum);
                            return;
                        }
                    }
                    if(currentFrame >= PB.positionGroup[length-1].frame)
                    {
                        Vector3 delta = new Vector3(
                            PB.positionGroup[length-1].right,PB.positionGroup[length-1].up,PB.positionGroup[length-1].forward);
                        character.gameObject.transform.position = initialPosition + character.transform.TransformDirection(delta);

                    }
                }
            }

        }

    }
}

